package de.sordul.model;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import de.sordul.LibEGK;
import de.sordul.SCUtils;

/**
 * Represents the patient data stored on an EGK smartcard.
 */
public class PatientData {

	String id, firstName, lastName, postalCode, city, countryCode, street;
	Date birthDate;
	int gender;
	Document doc;
	
	/**
	 * Extracts the personal data from a RawData object.
	 * @param data RawData
	 * @throws SAXException 
	 * @throws ParserConfigurationException 
	 * @throws IOException 
	 */
	public PatientData(RawData data) throws IOException, ParserConfigurationException, SAXException, ParseException {
		NodeList rootNodes, pDataNodes, addressNodes;
		Node node;
		
		// Parse only when data is present and the response code indicates success
		if(Arrays.equals(data.getResponseCode(), SCUtils.stringToBytes(LibEGK.EGK_STATUS_SUCCESS)) && data.getData() != null) {
			doc = SCUtils.byteToXML(data.getData());
			rootNodes = doc.getDocumentElement().getFirstChild().getChildNodes();
			
			for(int i=0; i < rootNodes.getLength(); i++) {
				node = rootNodes.item(i);				
				
				// Insurance number
				if(node.getNodeName() == "vsdp:Versicherten_ID") {
					id = node.getTextContent();
				}
				
				
				if(node.getNodeName() == "vsdp:Person") {
					pDataNodes = node.getChildNodes();
					for(int j=0; j < pDataNodes.getLength(); j++) {
						node = pDataNodes.item(j);
						
						// Birth date
						if(node.getNodeName() == "vsdp:Geburtsdatum") {
							DateFormat formatter = new SimpleDateFormat( "yyyyMMdd" );
							birthDate = formatter.parse( node.getTextContent() );
						}
						
						// First name
						if(node.getNodeName() == "vsdp:Vorname") {
							firstName = node.getTextContent();
						}
						
						// Last name
						if(node.getNodeName() == "vsdp:Nachname") {
							lastName = node.getTextContent();
						}
						
						// Gender
						if(node.getNodeName() == "vsdp:Geschlecht") {
							if(node.getTextContent().equals("M")) {
								gender = 0;
							} else {
								gender = 1;
							}
						}
						
						// Address
						if(node.getNodeName() == "vsdp:StrassenAdresse") {
							addressNodes = node.getChildNodes();
							
							for(int k=0; k < addressNodes.getLength(); k++) {
								node = addressNodes.item(k);
								
								// Postal code
								if(node.getNodeName() == "vsdp:Postleitzahl") {
									postalCode = node.getTextContent();
								}
								
								// City
								if(node.getNodeName() == "vsdp:Ort") {
									city = node.getTextContent();
								}					
								
								// Country
								if(node.getNodeName() == "vsdp:Land") {
									countryCode = node.getFirstChild().getTextContent();
								}	
								
								// Strees
								if(node.getNodeName() == "vsdp:Strasse") {
									street = node.getTextContent();
								}	
								
							}
						}
						
					}
				}
			}
		}
	}
	
	/**
	 * Returns the insurance number of this patient.
	 * @return Insurance number
	 */
	public String getId() {
		return id;
	}
	
	/**
	 * Returns the patients first name.
	 * @return First name
	 */
	public String getFirstName() {
		return firstName;
	}
	
	/**
	 * Returns the patients last name.
	 * @return Last name
	 */
	public String getLastName() {
		return lastName;
	}
	
	/**
	 * Returns the patients postal code.
	 * @return Postal code
	 */
	public String getPostalCode() {
		return postalCode;
	}
	
	/**
	 * Returns the patients city.
	 * @return City
	 */
	public String getCity() {
		return city;
	}
	
	/**
	 * Returns the patients country code.
	 * @return Country code
	 */
	public String getCountryCode() {
		return countryCode;
	}
	
	/**
	 * Returns the patients street.
	 * @return Street
	 */
	public String getStreet() {
		return street;
	}
	
	/**
	 * Returns the patients birth date.
	 * @return Birth date
	 */
	public Date getBirthDate() {
		return birthDate;
	}
	
	/**
	 * Returns the patients gender (0 = man, 1 = woman).
	 * @return Gender
	 */
	public int getGender() {
		return gender;
	}
}
